using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using PickGold.Charting;

namespace PickGold.Charting.ChartTypes
{
	internal class AreaChart : SplineChart
	{
		protected GraphicsPath areaPath;
		protected PointF axisPos = PointF.Empty;
		protected bool gradientFill;

		public AreaChart()
		{
			base.drawOutsideLines = true;
			base.lineTension = 0f;
			this.axisPos = PointF.Empty;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && (this.areaPath != null))
			{
				this.areaPath.Dispose();
				this.areaPath = null;
			}
			base.Dispose(disposing);
		}

		protected override GraphicsPath Draw3DSurface(ChartArea area, ChartGraphics graph, Matrix3D matrix, LightStyle lightStyle, DataPoint3D prevDataPointEx, float positionZ, float depth, ArrayList points, int pointIndex, int pointLoopIndex, float tension, DrawingOperationTypes operationType, float topDarkening, float bottomDarkening, PointF thirdPointPosition, PointF fourthPointPosition, bool clippedSegment)
		{
			GraphicsPath path = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) ? new GraphicsPath() : null;
			if (base.centerPointIndex == 0x7fffffff)
			{
				base.centerPointIndex = base.GetCenterPointIndex(points);
			}
			DataPoint3D secondPoint = (DataPoint3D)points[pointIndex];
			int neighborPointIndex = pointIndex;
			DataPoint3D firstPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
			bool reversed = false;
			if (firstPoint.index > secondPoint.index)
			{
				DataPoint3D pointd3 = firstPoint;
				firstPoint = secondPoint;
				secondPoint = pointd3;
				reversed = true;
			}
			if ((matrix.Perspective != 0f) && (base.centerPointIndex != 0x7fffffff))
			{
				neighborPointIndex = pointIndex;
				if (pointIndex != (base.centerPointIndex + 1))
				{
					firstPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
				}
				else if (!area.ReverseSeriesOrder)
				{
					secondPoint = ChartGraphics.FindPointByIndex(points, firstPoint.index + 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
				}
				else
				{
					firstPoint = secondPoint;
					secondPoint = ChartGraphics.FindPointByIndex(points, secondPoint.index - 1, base.multiSeries ? secondPoint : null, ref neighborPointIndex);
				}
			}
			if ((firstPoint != null) && (secondPoint != null))
			{
				reversed = false;
				for (int i = 1; (pointIndex + i) < points.Count; i++)
				{
					DataPoint3D pointd4 = (DataPoint3D)points[pointIndex + i];
					if (pointd4.dataPoint.series.Name == firstPoint.dataPoint.series.Name)
					{
						if (pointd4.index == firstPoint.index)
						{
							reversed = true;
						}
						break;
					}
				}
				if (tension == 0f)
				{
					return this.Draw3DSurface(firstPoint, secondPoint, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, LineSegmentType.Single, topDarkening, bottomDarkening, thirdPointPosition, fourthPointPosition, clippedSegment, true, true);
				}
				GraphicsPath path2 = graph.GetSplineFlattenPath(area, positionZ, firstPoint, secondPoint, points, tension, true, false, 0);
				PointF[] pathPoints = null;
				reversed = pointIndex < neighborPointIndex;
				if (reversed)
				{
					path2.Reverse();
				}
				pathPoints = path2.PathPoints;
				DataPoint3D pointd5 = new DataPoint3D();
				DataPoint3D pointd6 = new DataPoint3D();
				LineSegmentType middle = LineSegmentType.Middle;
				for (int j = 1; j < pathPoints.Length; j++)
				{
					if (!reversed)
					{
						pointd5.dataPoint = firstPoint.dataPoint;
						pointd5.index = firstPoint.index;
						pointd5.xPosition = pathPoints[j - 1].X;
						pointd5.yPosition = pathPoints[j - 1].Y;
						pointd6.dataPoint = secondPoint.dataPoint;
						pointd6.index = secondPoint.index;
						pointd6.xPosition = pathPoints[j].X;
						pointd6.yPosition = pathPoints[j].Y;
					}
					else
					{
						pointd6.dataPoint = firstPoint.dataPoint;
						pointd6.index = firstPoint.index;
						pointd6.xPosition = pathPoints[j - 1].X;
						pointd6.yPosition = pathPoints[j - 1].Y;
						pointd5.dataPoint = secondPoint.dataPoint;
						pointd5.index = secondPoint.index;
						pointd5.xPosition = pathPoints[j].X;
						pointd5.yPosition = pathPoints[j].Y;
					}
					middle = LineSegmentType.Middle;
					if (j == 1)
					{
						if (!reversed)
						{
							middle = LineSegmentType.First;
						}
						else
						{
							middle = LineSegmentType.Last;
						}
					}
					else if (j == (pathPoints.Length - 1))
					{
						if (!reversed)
						{
							middle = LineSegmentType.Last;
						}
						else
						{
							middle = LineSegmentType.First;
						}
					}
					area.IterationCounter = 0;
					GraphicsPath addingPath = this.Draw3DSurface(pointd5, pointd6, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, 0f, operationType, middle, topDarkening, bottomDarkening, new PointF(float.NaN, float.NaN), new PointF(float.NaN, float.NaN), clippedSegment, true, true);
					if (((path != null) && (addingPath != null)) && (addingPath.PointCount > 0))
					{
						path.AddPath(addingPath, true);
					}
				}
			}
			return path;
		}

		protected override GraphicsPath Draw3DSurface(DataPoint3D firstPoint, DataPoint3D secondPoint, bool reversed, ChartArea area, ChartGraphics graph, Matrix3D matrix, LightStyle lightStyle, DataPoint3D prevDataPointEx, float positionZ, float depth, ArrayList points, int pointIndex, int pointLoopIndex, float tension, DrawingOperationTypes operationType, LineSegmentType surfaceSegmentType, float topDarkening, float bottomDarkening, PointF thirdPointPosition, PointF fourthPointPosition, bool clippedSegment, bool clipOnTop, bool clipOnBottom)
		{
			GraphicsPath resultPath = ((operationType & DrawingOperationTypes.CalcElementPath) == DrawingOperationTypes.CalcElementPath) ? new GraphicsPath() : null;
			if ((Math.Round(firstPoint.xPosition, 3) != Math.Round(secondPoint.xPosition, 3)) || (Math.Round(firstPoint.yPosition, 3) != Math.Round(secondPoint.yPosition, 3)))
			{
				PointF tf;
				PointF tf2;
				DataPoint3D pointd = secondPoint;
				if (prevDataPointEx.dataPoint.IsEmpty)
				{
					pointd = prevDataPointEx;
				}
				else if (firstPoint.index > secondPoint.index)
				{
					pointd = firstPoint;
				}
				Color gray = base.useBorderColor ? pointd.dataPoint.BorderColor : pointd.dataPoint.Color;
				ChartDashStyle borderDashStyle = pointd.dataPoint.BorderDashStyle;
				if (pointd.dataPoint.IsEmpty && (pointd.dataPoint.Color == Color.Empty))
				{
					gray = Color.Gray;
				}
				if (pointd.dataPoint.IsEmpty && (pointd.dataPoint.BorderDashStyle == ChartDashStyle.NotSet))
				{
					borderDashStyle = ChartDashStyle.Solid;
				}
				float num = (float)Math.Round(base.VAxis.GetPosition(base.VAxis.Crossing), 3);
				float x = (float)Math.Min(firstPoint.xPosition, secondPoint.xPosition);
				float num3 = (float)Math.Min(firstPoint.yPosition, secondPoint.yPosition);
				num3 = Math.Min(num3, num);
				float num4 = (float)Math.Max(firstPoint.xPosition, secondPoint.xPosition);
				float num5 = (float)Math.Max(firstPoint.yPosition, secondPoint.yPosition);
				num5 = Math.Max(num5, num);
				RectangleF position = new RectangleF(x, num3, num4 - x, num5 - num3);
				SurfaceNames visibleSurfaces = graph.GetVisibleSurfaces(position, positionZ, depth, matrix);
				bool upSideDown = false;
				if ((((decimal)firstPoint.yPosition) >= ((decimal)num)) && (((decimal)secondPoint.yPosition) >= ((decimal)num)))
				{
					upSideDown = true;
					bool flag2 = (visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top;
					bool flag3 = (visibleSurfaces & SurfaceNames.Bottom) == SurfaceNames.Bottom;
					visibleSurfaces ^= SurfaceNames.Bottom;
					visibleSurfaces ^= SurfaceNames.Top;
					if (flag2)
					{
						visibleSurfaces |= SurfaceNames.Bottom;
					}
					if (flag3)
					{
						visibleSurfaces |= SurfaceNames.Top;
					}
				}
				this.GetTopSurfaceVisibility(area, firstPoint, secondPoint, upSideDown, positionZ, depth, matrix, ref visibleSurfaces);
				this.GetBottomPointsPosition(base.Common, area, num, ref firstPoint, ref secondPoint, thirdPointPosition, fourthPointPosition, out tf, out tf2);
				if (!float.IsNaN(thirdPointPosition.Y))
				{
					tf.Y = thirdPointPosition.Y;
				}
				if (!float.IsNaN(fourthPointPosition.Y))
				{
					tf2.Y = fourthPointPosition.Y;
				}
				if ((float.IsNaN(tf.X) || float.IsNaN(tf.Y)) || (float.IsNaN(tf2.X) || float.IsNaN(tf2.Y)))
				{
					return resultPath;
				}
				if (clipOnTop && base.ClipTopPoints(resultPath, ref firstPoint, ref secondPoint, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening))
				{
					return resultPath;
				}
				if (clipOnBottom && base.ClipBottomPoints(resultPath, ref firstPoint, ref secondPoint, ref tf, ref tf2, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening))
				{
					return resultPath;
				}
				if (((Math.Round((decimal)firstPoint.yPosition, 3) > (((decimal)num) + 0.001M)) && (Math.Round((decimal)secondPoint.yPosition, 3) < (((decimal)num) - 0.001M))) || ((Math.Round((decimal)firstPoint.yPosition, 3) < (((decimal)num) - 0.001M)) && (Math.Round((decimal)secondPoint.yPosition, 3) > (((decimal)num) + 0.001M))))
				{
					DataPoint3D pointd2 = this.GetAxisIntersection(firstPoint, secondPoint, num);
					for (int i = 0; i <= 1; i++)
					{
						GraphicsPath addingPath = null;
						if (((i == 0) && !reversed) || ((i == 1) && reversed))
						{
							pointd2.dataPoint = secondPoint.dataPoint;
							pointd2.index = secondPoint.index;
							addingPath = this.Draw3DSurface(firstPoint, pointd2, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening, new PointF(float.NaN, float.NaN), new PointF(float.NaN, float.NaN), clippedSegment, clipOnTop, clipOnBottom);
						}
						if (((i == 1) && !reversed) || ((i == 0) && reversed))
						{
							pointd2.dataPoint = firstPoint.dataPoint;
							pointd2.index = firstPoint.index;
							addingPath = this.Draw3DSurface(pointd2, secondPoint, reversed, area, graph, matrix, lightStyle, prevDataPointEx, positionZ, depth, points, pointIndex, pointLoopIndex, tension, operationType, surfaceSegmentType, topDarkening, bottomDarkening, new PointF(float.NaN, float.NaN), new PointF(float.NaN, float.NaN), clippedSegment, clipOnTop, clipOnBottom);
						}
						if (((resultPath != null) && (addingPath != null)) && (addingPath.PointCount > 0))
						{
							resultPath.AddPath(addingPath, true);
						}
					}
					return resultPath;
				}
				if ((Math.Round(firstPoint.xPosition, 3) != Math.Round(secondPoint.xPosition, 3)) || (Math.Round(firstPoint.yPosition, 3) != Math.Round(secondPoint.yPosition, 3)))
				{
					for (int j = 1; j <= 2; j++)
					{
						SurfaceNames[] namesArray = new SurfaceNames[] { SurfaceNames.Back, SurfaceNames.Bottom, SurfaceNames.Top, SurfaceNames.Left, SurfaceNames.Right, SurfaceNames.Front };
						LineSegmentType middle = LineSegmentType.Middle;
						foreach (SurfaceNames names2 in namesArray)
						{
							DataPoint3D pointd11;
							DataPoint3D pointd12;
							SurfaceNames left;
							DataPoint3D pointd13;
							DataPoint3D pointd14;
							if ((ChartGraphics.ShouldDrawLineChartSurface(area, area.ReverseSeriesOrder, names2, visibleSurfaces, gray, points, firstPoint, secondPoint, base.multiSeries, ref middle) != j) || (((base.allPointsLoopsNumber == 2) && ((operationType & DrawingOperationTypes.DrawElement) == DrawingOperationTypes.DrawElement)) && (((pointLoopIndex == 0) && ((names2 == SurfaceNames.Front) || ((j == 2) && ((names2 == SurfaceNames.Left) || (names2 == SurfaceNames.Right))))) || (((pointLoopIndex == 1) && ((names2 == SurfaceNames.Back) || (names2 != SurfaceNames.Front))) && ((j == 1) || ((names2 != SurfaceNames.Left) && (names2 != SurfaceNames.Right)))))))
							{
								goto Label_0C75;
							}
							Color backColor = gray;
							Color borderColor = pointd.dataPoint.BorderColor;
							if (j == 1)
							{
								if (backColor.A == 0xff)
								{
									goto Label_0C75;
								}
								backColor = Color.Transparent;
								if (borderColor == Color.Empty)
								{
									borderColor = ChartGraphics.GetGradientColor(gray, Color.Black, 0.2);
								}
							}
							bool showPointLines = base.showPointLines;
							if (surfaceSegmentType == LineSegmentType.Middle)
							{
								showPointLines = false;
							}
							if ((clippedSegment && (names2 != SurfaceNames.Top)) && (names2 != SurfaceNames.Bottom))
							{
								goto Label_0C75;
							}
							GraphicsPath path3 = null;
							switch (names2)
							{
								case SurfaceNames.Front:
									pointd13 = new DataPoint3D();
									pointd13.index = firstPoint.index;
									pointd13.dataPoint = firstPoint.dataPoint;
									pointd13.xPosition = firstPoint.xPosition;
									pointd13.yPosition = tf.Y;
									pointd14 = new DataPoint3D();
									pointd14.index = secondPoint.index;
									pointd14.dataPoint = secondPoint.dataPoint;
									pointd14.xPosition = secondPoint.xPosition;
									pointd14.yPosition = tf2.Y;
									if (area.ReverseSeriesOrder)
									{
										if (middle != LineSegmentType.First)
										{
											goto Label_0BD0;
										}
										middle = LineSegmentType.Last;
									}
									goto Label_0BD8;

								case SurfaceNames.Back:
									pointd11 = new DataPoint3D();
									pointd11.index = firstPoint.index;
									pointd11.dataPoint = firstPoint.dataPoint;
									pointd11.xPosition = firstPoint.xPosition;
									pointd11.yPosition = tf.Y;
									pointd12 = new DataPoint3D();
									pointd12.index = secondPoint.index;
									pointd12.dataPoint = secondPoint.dataPoint;
									pointd12.xPosition = secondPoint.xPosition;
									pointd12.yPosition = tf2.Y;
									left = 0;
									if (showPointLines)
									{
										if (surfaceSegmentType != LineSegmentType.Single)
										{
											goto Label_0B00;
										}
										left = SurfaceNames.Right | SurfaceNames.Left;
									}
									goto Label_0B12;

								case (SurfaceNames.Back | SurfaceNames.Front):
									goto Label_0C4A;

								case SurfaceNames.Left:
									if (((surfaceSegmentType == LineSegmentType.Single) || (!area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.First))) || (area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.Last)))
									{
										DataPoint3D pointd5 = (firstPoint.xPosition <= secondPoint.xPosition) ? firstPoint : secondPoint;
										DataPoint3D pointd6 = new DataPoint3D();
										pointd6.index = pointd5.index;
										pointd6.dataPoint = pointd5.dataPoint;
										pointd6.xPosition = pointd5.xPosition;
										pointd6.yPosition = (firstPoint.xPosition <= secondPoint.xPosition) ? ((double)tf.Y) : ((double)tf2.Y);
										DataPoint3D pointd7 = new DataPoint3D();
										pointd7.index = pointd5.index;
										pointd7.dataPoint = pointd5.dataPoint;
										pointd7.xPosition = pointd5.xPosition;
										pointd7.yPosition = pointd5.yPosition;
										path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, backColor, borderColor, pointd.dataPoint.BorderWidth, borderDashStyle, pointd6, pointd7, points, pointIndex, 0f, operationType, LineSegmentType.Single, true, true, area.ReverseSeriesOrder, base.multiSeries, 0, true);
									}
									goto Label_0C4A;

								case SurfaceNames.Right:
									if (((surfaceSegmentType == LineSegmentType.Single) || (!area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.Last))) || (area.ReverseSeriesOrder && (surfaceSegmentType == LineSegmentType.First)))
									{
										DataPoint3D pointd8 = (secondPoint.xPosition >= firstPoint.xPosition) ? secondPoint : firstPoint;
										DataPoint3D pointd9 = new DataPoint3D();
										pointd9.index = pointd8.index;
										pointd9.dataPoint = pointd8.dataPoint;
										pointd9.xPosition = pointd8.xPosition;
										pointd9.yPosition = (secondPoint.xPosition >= firstPoint.xPosition) ? ((double)tf2.Y) : ((double)tf.Y);
										DataPoint3D pointd10 = new DataPoint3D();
										pointd10.index = pointd8.index;
										pointd10.dataPoint = pointd8.dataPoint;
										pointd10.xPosition = pointd8.xPosition;
										pointd10.yPosition = pointd8.yPosition;
										path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, backColor, borderColor, pointd.dataPoint.BorderWidth, borderDashStyle, pointd9, pointd10, points, pointIndex, 0f, operationType, LineSegmentType.Single, true, true, area.ReverseSeriesOrder, base.multiSeries, 0, true);
									}
									goto Label_0C4A;

								case SurfaceNames.Top:
									{
										Color color4 = (topDarkening == 0f) ? backColor : ChartGraphics.GetGradientColor(backColor, Color.Black, (double)topDarkening);
										Color color5 = (topDarkening == 0f) ? borderColor : ChartGraphics.GetGradientColor(borderColor, Color.Black, (double)topDarkening);
										path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, color4, color5, pointd.dataPoint.BorderWidth, borderDashStyle, firstPoint, secondPoint, points, pointIndex, 0f, operationType, surfaceSegmentType, showPointLines, false, area.ReverseSeriesOrder, base.multiSeries, 0, true);
										break;
									}
								case SurfaceNames.Bottom:
									{
										DataPoint3D pointd3 = new DataPoint3D();
										pointd3.index = firstPoint.index;
										pointd3.dataPoint = firstPoint.dataPoint;
										pointd3.xPosition = firstPoint.xPosition;
										pointd3.yPosition = tf.Y;
										DataPoint3D pointd4 = new DataPoint3D();
										pointd4.index = secondPoint.index;
										pointd4.dataPoint = secondPoint.dataPoint;
										pointd4.xPosition = secondPoint.xPosition;
										pointd4.yPosition = tf2.Y;
										Color color6 = (bottomDarkening == 0f) ? backColor : ChartGraphics.GetGradientColor(backColor, Color.Black, (double)topDarkening);
										Color color7 = (bottomDarkening == 0f) ? borderColor : ChartGraphics.GetGradientColor(borderColor, Color.Black, (double)topDarkening);
										path3 = graph.Draw3DSurface(area, matrix, lightStyle, names2, positionZ, depth, color6, color7, pointd.dataPoint.BorderWidth, borderDashStyle, pointd3, pointd4, points, pointIndex, 0f, operationType, surfaceSegmentType, showPointLines, false, area.ReverseSeriesOrder, base.multiSeries, 0, true);
										goto Label_0C4A;
									}
							}
							goto Label_0C4A;
						Label_0B00:
							if (surfaceSegmentType == LineSegmentType.First)
							{
								left = SurfaceNames.Left;
							}
							else if (surfaceSegmentType == LineSegmentType.Last)
							{
								left = SurfaceNames.Right;
							}
						Label_0B12:
							path3 = graph.Draw3DPolygon(area, matrix, names2, positionZ, backColor, borderColor, pointd.dataPoint.BorderWidth, firstPoint, secondPoint, pointd12, pointd11, operationType, middle, left);
							goto Label_0C4A;
						Label_0BD0:
							if (middle == LineSegmentType.Last)
							{
								middle = LineSegmentType.First;
							}
						Label_0BD8:
							if ((surfaceSegmentType != LineSegmentType.Single) && (((surfaceSegmentType == LineSegmentType.Middle) || ((surfaceSegmentType == LineSegmentType.First) && (middle != LineSegmentType.First))) || ((surfaceSegmentType == LineSegmentType.Last) && (middle != LineSegmentType.Last))))
							{
								middle = LineSegmentType.Middle;
							}
							SurfaceNames thinBorders = 0;
							if (showPointLines)
							{
								if (surfaceSegmentType == LineSegmentType.Single)
								{
									thinBorders = SurfaceNames.Right | SurfaceNames.Left;
								}
								else if (surfaceSegmentType == LineSegmentType.First)
								{
									thinBorders = SurfaceNames.Left;
								}
								else if (surfaceSegmentType == LineSegmentType.Last)
								{
									thinBorders = SurfaceNames.Right;
								}
							}
							path3 = graph.Draw3DPolygon(area, matrix, names2, positionZ + depth, backColor, borderColor, pointd.dataPoint.BorderWidth, firstPoint, secondPoint, pointd14, pointd13, operationType, middle, thinBorders);
						Label_0C4A:
							if (((j == 2) && (resultPath != null)) && ((path3 != null) && (path3.PointCount > 0)))
							{
								resultPath.CloseFigure();
								resultPath.SetMarkers();
								resultPath.AddPath(path3, true);
							}
						Label_0C75: ;
						}
					}
				}
			}
			return resultPath;
		}

		protected override void DrawLine(ChartGraphics graph, CommonElements common, DataPoint point, Series series, PointF[] points, int pointIndex, float tension)
		{
			if (pointIndex > 0)
			{
				if (this.Series != null)
				{
					if (this.Series.Name != series.Name)
					{
						this.FillLastSeriesGradient(graph);
						this.Series = series;
					}
				}
				else
				{
					this.Series = series;
				}
				PointF tf = points[pointIndex - 1];
				PointF tf2 = points[pointIndex];
				tf.X = (float)Math.Round((double)tf.X);
				tf.Y = (float)Math.Round((double)tf.Y);
				tf2.X = (float)Math.Round((double)tf2.X);
				tf2.Y = (float)Math.Round((double)tf2.Y);
				if (this.axisPos == PointF.Empty)
				{
					this.axisPos.X = (float)base.VAxis.GetPosition(base.VAxis.Crossing);
					this.axisPos.Y = (float)base.VAxis.GetPosition(base.VAxis.Crossing);
					this.axisPos = graph.GetAbsolutePoint(this.axisPos);
					this.axisPos.X = (float)Math.Round((double)this.axisPos.X);
					this.axisPos.Y = (float)Math.Round((double)this.axisPos.Y);
				}
				Color backColor = point.Color;
				Color borderColor = point.BorderColor;
				int borderWidth = point.BorderWidth;
				ChartDashStyle borderDashStyle = point.BorderDashStyle;
				Brush brush = null;
				if (point.BackHatchStyle != ChartHatchStyle.None)
				{
					brush = graph.GetHatchBrush(point.BackHatchStyle, backColor, point.BackSecondaryColor);
				}
				else if (point.BackGradientStyle != GradientStyle.None)
				{
					this.gradientFill = true;
					this.Series = point.series;
				}
				else if (((point.BackImage.Length > 0) && (point.BackImageWrapMode != ChartImageWrapMode.Unscaled)) && (point.BackImageWrapMode != ChartImageWrapMode.Scaled))
				{
					brush = graph.GetTextureBrush(point.BackImage, point.BackImageTransparentColor, point.BackImageWrapMode, point.Color);
				}
				else
				{
					brush = new SolidBrush(backColor);
				}
				GraphicsPath path = new GraphicsPath();
				path.AddLine(tf.X, this.axisPos.Y, tf.X, tf.Y);
				if (base.lineTension == 0f)
				{
					path.AddLine(points[pointIndex - 1], points[pointIndex]);
				}
				else
				{
					path.AddCurve(points, pointIndex - 1, 1, base.lineTension);
				}
				path.AddLine(tf2.X, tf2.Y, tf2.X, this.axisPos.Y);
				if (((series.ShadowColor != Color.Empty) && (series.ShadowOffset != 0)) && ((backColor != Color.Empty) && (backColor != Color.Transparent)))
				{
					Region region = new Region(path);
					using (Brush brush2 = new SolidBrush((series.ShadowColor.A != 0xff) ? series.ShadowColor : Color.FromArgb(backColor.A / 2, series.ShadowColor)))
					{
						GraphicsState gstate = graph.Save();
						Region clip = null;
						Region region3 = null;
						if (!graph.IsClipEmpty && !graph.Clip.IsInfinite(graph.Graphics))
						{
							region3 = graph.Clip.Clone();
							clip = graph.Clip;
							clip.Translate(series.ShadowOffset, series.ShadowOffset);
							graph.Clip = clip;
						}
						graph.TranslateTransform((float)series.ShadowOffset, (float)series.ShadowOffset);
						if (graph.SmoothingMode != SmoothingMode.None)
						{
							using (Pen pen = new Pen(brush2, 1f))
							{
								if (base.lineTension == 0f)
								{
									graph.DrawLine(pen, points[pointIndex - 1], points[pointIndex]);
								}
								else
								{
									graph.DrawCurve(pen, points, pointIndex - 1, 1, base.lineTension);
								}
							}
						}
						graph.FillRegion(brush2, region);
						graph.Restore(gstate);
						if ((clip != null) && (region3 != null))
						{
							graph.Clip = region3;
						}
					}
				}
				if (!this.gradientFill)
				{
					SmoothingMode smoothingMode = graph.SmoothingMode;
					graph.SmoothingMode = SmoothingMode.None;
					graph.FillPath(brush, path);
					graph.SmoothingMode = smoothingMode;
					if (graph.SmoothingMode != SmoothingMode.None)
					{
						graph.StartHotRegion(point);
						using (Pen pen2 = new Pen(brush, 1f))
						{
							if (base.lineTension == 0f)
							{
								if ((points[pointIndex - 1].X != points[pointIndex].X) && (points[pointIndex - 1].Y != points[pointIndex].Y))
								{
									graph.DrawLine(pen2, points[pointIndex - 1], points[pointIndex]);
								}
							}
							else
							{
								graph.DrawCurve(pen2, points, pointIndex - 1, 1, base.lineTension);
							}
						}
						graph.EndHotRegion();
					}
				}
				if (brush != null)
				{
					brush.Dispose();
				}
				if (this.areaPath == null)
				{
					this.areaPath = new GraphicsPath();
					this.areaPath.AddLine(tf.X, this.axisPos.Y, tf.X, tf.Y);
				}
				if (base.lineTension == 0f)
				{
					this.areaPath.AddLine(points[pointIndex - 1], points[pointIndex]);
				}
				else
				{
					this.areaPath.AddCurve(points, pointIndex - 1, 1, base.lineTension);
				}
				if ((borderWidth > 0) && (borderColor != Color.Empty))
				{
					Pen pen3 = new Pen((borderColor != Color.Empty) ? borderColor : backColor, (float)borderWidth);
					pen3.DashStyle = graph.GetPenStyle(borderDashStyle);
					pen3.StartCap = LineCap.Round;
					pen3.EndCap = LineCap.Round;
					if (base.lineTension == 0f)
					{
						graph.DrawLine(pen3, points[pointIndex - 1], points[pointIndex]);
					}
					else
					{
						graph.DrawCurve(pen3, points, pointIndex - 1, 1, base.lineTension);
					}
				}
				if (common.ProcessModeRegions)
				{
					GraphicsPath path2 = new GraphicsPath();
					path2.AddLine(tf.X, this.axisPos.Y, tf.X, tf.Y);
					if (base.lineTension == 0f)
					{
						path2.AddLine(points[pointIndex - 1], points[pointIndex]);
					}
					else
					{
						path2.AddCurve(points, pointIndex - 1, 1, base.lineTension);
						path2.Flatten();
					}
					path2.AddLine(tf2.X, tf2.Y, tf2.X, this.axisPos.Y);
					path2.AddLine(tf2.X, this.axisPos.Y, tf.X, this.axisPos.Y);
					PointF empty = PointF.Empty;
					float[] coord = new float[path2.PointCount * 2];
					PointF[] pathPoints = path2.PathPoints;
					for (int i = 0; i < path2.PointCount; i++)
					{
						empty = graph.GetRelativePoint(pathPoints[i]);
						coord[2 * i] = empty.X;
						coord[(2 * i) + 1] = empty.Y;
					}
					common.HotRegionsList.AddHotRegion(path2, false, coord, point, series.Name, pointIndex);
					if (((borderWidth > 1) && (borderDashStyle != ChartDashStyle.NotSet)) && (borderColor != Color.Empty))
					{
						try
						{
							path2.Dispose();
							path2 = new GraphicsPath();
							if (base.lineTension == 0f)
							{
								path2.AddLine(points[pointIndex - 1], points[pointIndex]);
							}
							else
							{
								path2.AddCurve(points, pointIndex - 1, 1, base.lineTension);
								path2.Flatten();
							}
							path2.Widen(new Pen(backColor, (float)(borderWidth + 2)));
						}
						catch (OutOfMemoryException)
						{
						}
						catch (ArgumentException)
						{
						}
						empty = PointF.Empty;
						coord = new float[path2.PointCount * 2];
						PointF[] tfArray2 = path2.PathPoints;
						for (int j = 0; j < tfArray2.Length; j++)
						{
							empty = graph.GetRelativePoint(tfArray2[j]);
							coord[2 * j] = empty.X;
							coord[(2 * j) + 1] = empty.Y;
						}
						common.HotRegionsList.AddHotRegion(path2, false, coord, point, series.Name, pointIndex);
					}
					path2.Dispose();
				}
			}
		}

		private void FillLastSeriesGradient(ChartGraphics graph)
		{
			if (this.areaPath != null)
			{
				this.areaPath.AddLine(this.areaPath.GetLastPoint().X, this.areaPath.GetLastPoint().Y, this.areaPath.GetLastPoint().X, this.axisPos.Y);
			}
			if (this.gradientFill && (this.areaPath != null))
			{
				graph.SetClip(base.Area.PlotAreaPosition.ToRectangleF());
				using (Brush brush = graph.GetGradientBrush(this.areaPath.GetBounds(), this.Series.Color, this.Series.BackSecondaryColor, this.Series.BackGradientStyle))
				{
					graph.FillPath(brush, this.areaPath);
					this.gradientFill = false;
				}
				graph.ResetClip();
			}
			if (this.areaPath != null)
			{
				this.areaPath.Dispose();
				this.areaPath = null;
			}
		}

		internal DataPoint3D GetAxisIntersection(DataPoint3D firstPoint, DataPoint3D secondPoint, float axisPosition)
		{
			DataPoint3D pointd = new DataPoint3D();
			pointd.yPosition = axisPosition;
			pointd.xPosition = (((axisPosition - firstPoint.yPosition) * (secondPoint.xPosition - firstPoint.xPosition)) / (secondPoint.yPosition - firstPoint.yPosition)) + firstPoint.xPosition;
			return pointd;
		}

		protected virtual void GetBottomPointsPosition(CommonElements common, ChartArea area, float axisPosition, ref DataPoint3D firstPoint, ref DataPoint3D secondPoint, PointF thirdPointPosition, PointF fourthPointPosition, out PointF thirdPoint, out PointF fourthPoint)
		{
			thirdPoint = new PointF((float)firstPoint.xPosition, axisPosition);
			fourthPoint = new PointF((float)secondPoint.xPosition, axisPosition);
		}

		protected override float GetDefaultTension()
		{
			return 0f;
		}

		public override Image GetImage(ChartTypeRegistry registry)
		{
			return (Image)registry.ResourceManager.GetObject(this.Name + "ChartType");
		}

		public override LegendImageStyle GetLegendImageStyle(Series series)
		{
			return LegendImageStyle.Rectangle;
		}

		protected override int GetPointLoopNumber(bool selection, ArrayList pointsArray)
		{
			if (selection)
			{
				return 1;
			}
			int num = 1;
			foreach (object obj2 in pointsArray)
			{
				DataPoint3D pointd = (DataPoint3D)obj2;
				if (pointd.dataPoint.Color.A != 0xff)
				{
					num = 2;
				}
			}
			return num;
		}

		protected virtual void GetTopSurfaceVisibility(ChartArea area, DataPoint3D firstPoint, DataPoint3D secondPoint, bool upSideDown, float positionZ, float depth, Matrix3D matrix, ref SurfaceNames visibleSurfaces)
		{
			if ((visibleSurfaces & SurfaceNames.Top) == SurfaceNames.Top)
			{
				visibleSurfaces ^= SurfaceNames.Top;
			}
			Point3D[] points = new Point3D[3];
			if (!area.ReverseSeriesOrder)
			{
				if ((!upSideDown && (firstPoint.xPosition <= secondPoint.xPosition)) || (upSideDown && (firstPoint.xPosition >= secondPoint.xPosition)))
				{
					points[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth);
					points[1] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
					points[2] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
				}
				else
				{
					points[0] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth);
					points[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
					points[2] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
				}
			}
			else if ((!upSideDown && (secondPoint.xPosition <= firstPoint.xPosition)) || (upSideDown && (secondPoint.xPosition >= firstPoint.xPosition)))
			{
				points[0] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ + depth);
				points[1] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
				points[2] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
			}
			else
			{
				points[0] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ + depth);
				points[1] = new Point3D((float)firstPoint.xPosition, (float)firstPoint.yPosition, positionZ);
				points[2] = new Point3D((float)secondPoint.xPosition, (float)secondPoint.yPosition, positionZ);
			}
			matrix.TransformPoints(points);
			if (ChartGraphics.IsSurfaceVisible(points[0], points[1], points[2]))
			{
				visibleSurfaces |= SurfaceNames.Top;
			}
		}

		protected override bool IsLineTensionSupported()
		{
			return false;
		}

		protected override void ProcessChartType(bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			this.gradientFill = false;
			this.axisPos = PointF.Empty;
			base.ProcessChartType(selection, graph, common, area, seriesToDraw);
			if (!area.Area3DStyle.Enable3D)
			{
				this.FillLastSeriesGradient(graph);
			}
		}

		public override string Name
		{
			get
			{
				return "Area";
			}
		}

		protected Series Series { set; get; }

		public override bool ZeroCrossing
		{
			get
			{
				return true;
			}
		}
	}
}

